package com.anlogic.sdk.utils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class XmlUtils {
	public static Document parseFile(File file) throws ParserConfigurationException, SAXException, IOException {
		InputSource inputSource = new InputSource(new FileInputStream(file));
		DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        Document doc = builder.parse(inputSource);
        return doc;
	}

	public static void saveFile(File file, Document doc) throws TransformerException {
		TransformerFactory transformerFactory = TransformerFactory.newInstance();
		Transformer transformer = null;
		try {
			String path = FileUtils.getPluginResourcePath("com.anlogic.sdk.utils", "prettyprint.xsl");
			String prettyTemplate = FileUtils.read(new File(path));
			transformer = transformerFactory.newTransformer(new StreamSource(new StringReader(prettyTemplate)));
		} catch (IOException e) {
			transformer = transformerFactory.newTransformer();
		}
		transformer.setOutputProperty(OutputKeys.INDENT, "yes");
		transformer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
		transformer.transform(new DOMSource(doc), new StreamResult(file));
	}
	
	public static String docToString(Document doc) throws TransformerException {
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
		Transformer transformer = null;
		try {
			String path = FileUtils.getPluginResourcePath("com.anlogic.sdk.utils", "prettyprint.xsl");
			String prettyTemplate = FileUtils.read(new File(path));
			transformer = transformerFactory.newTransformer(new StreamSource(new StringReader(prettyTemplate)));
		} catch (IOException e) {
			transformer = transformerFactory.newTransformer();
		}
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        transformer.transform(new DOMSource(doc), new StreamResult(bos));
        return bos.toString();
    }
	
    public static Document stringToDocument(String data) throws Exception {
        InputSource inputSource = new InputSource(new StringReader(data));
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = dbf.newDocumentBuilder();
        Document doc = builder.parse(inputSource);
        return doc;
    }
	
	public static Document newDocument() throws ParserConfigurationException {
		DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
		Document document = builder.newDocument();
		return document;
	}
	
    public static Node createNode(Document doc, String parentPath, String name) throws XPathExpressionException {
        XPathFactory factory = XPathFactory.newInstance();
        XPath xpath = factory.newXPath();
    	Node parentNode = (Node) xpath.evaluate(parentPath, doc, XPathConstants.NODE);
    	
		if (parentNode == null) {
			return null;	
		}
		
    	Element newElement = doc.createElement(name);
    	parentNode.appendChild(newElement);
    	return newElement;
    }
    
    public static Node createNode(Document doc, String parentPath, String name, String value) throws XPathExpressionException {
        XPathFactory factory = XPathFactory.newInstance();
        XPath xpath = factory.newXPath();
    	Node parentNode = (Node) xpath.evaluate(parentPath, doc, XPathConstants.NODE);
    	
		if (parentNode == null) {
			return null;	
		}
		
    	Element newElement = doc.createElement(name);
    	newElement.setTextContent(value);
    	parentNode.appendChild(newElement);
    	return newElement;
    }
	
    public static Node getNode(Document doc, String path) throws XPathExpressionException {
        XPathFactory factory = XPathFactory.newInstance();
        XPath xpath = factory.newXPath();
        Node node = (Node)xpath.evaluate(path, doc, XPathConstants.NODE);
        return node;
    }
    
    public static NodeList getNodes(Document doc, String path) throws XPathExpressionException {
        XPathFactory factory = XPathFactory.newInstance();
        XPath xpath = factory.newXPath();
        NodeList nodes = (NodeList)xpath.evaluate(path, doc, XPathConstants.NODESET);
        return nodes;
    }
    
    public static void setNodeTextContent(Document doc, String path, String value) throws XPathExpressionException {
        XPathFactory factory = XPathFactory.newInstance();
        XPath xpath = factory.newXPath();
        Node node = (Node)xpath.evaluate(path, doc, XPathConstants.NODE);
        node.setTextContent(value);
    }
    
    public static void setNodeValue(Document doc, String path, String value) throws XPathExpressionException {
        XPathFactory factory = XPathFactory.newInstance();
        XPath xpath = factory.newXPath();
        Node node = (Node)xpath.evaluate(path, doc, XPathConstants.NODE);
        node.setNodeValue(value);
    }
    
    public static void setNodeAttr(Document doc, String path, String value) throws XPathExpressionException {
    	Node node = getNode(doc, path);
    	if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
			node.setNodeValue(value);
		}
    }
}
